using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration.Provider;
using Accountability4net.Contact;

namespace Accountability4net
{
    /// <summary>
    /// Base class for providers. Concrete providers create and get implementors of the
    /// defined interfaces and concrete classes of base classes.
    /// </summary>
    public abstract class MonengineProviderBase: ProviderBase, IDisposable
    {
        /// <summary>
        /// Creates a new account
        /// </summary>
        /// <param name="number">A unique identifier for the account</param>
        /// <param name="type">The type of the account</param>
        /// <returns>A new account</returns>
        /// <exception cref="ArgumentException">
        /// Thrown if the <paramref name="number"/> is not unique
        /// </exception>
        public abstract IAccount CreateAccount(int number, AccountType type);
        /// <summary>
        /// Returns the account with the specified number.
        /// </summary>
        /// <param name="number">Unique identifier of the account</param>
        /// <returns>
        /// The account identified by <paramref name="number"/>
        /// or <code>null</code> if the account does not exist.
        /// </returns>
        public abstract IAccount GetAccount(int number);
        /// <summary>
        /// Get all the accounts in the system
        /// </summary>
        /// <returns>All accounts</returns>
        public virtual IList<IAccount> GetAccounts()
        {
            return GetAccounts(0, int.MaxValue);
        }
        /// <summary>
        /// Get accounts limited by parameters.
        /// </summary>
        /// <param name="from">The number of the first account to get in ascending order</param>
        /// <param name="limit">The maximum number of accounts to return</param>
        /// <returns>Returns accounts limited by from and limit</returns>
        public abstract IList<IAccount> GetAccounts(int from, int limit);
        /// <summary>
        /// Creates a new action
        /// </summary>
        /// <param name="type">Type of the action</param>
        /// <param name="account">The account on which to perform the action</param>
        /// <param name="amount">The amount of the action</param>
        /// <returns>A new action</returns>
        public abstract IAction CreateAction(ActionType type, IAccount account, decimal amount);
        /// <summary>
        /// Creates a new transaction
        /// </summary>
        /// <param name="timestamp">The time the transaction occured in real-life</param>
        /// <returns>A new transaction</returns>
        public abstract ITransaction CreateTransaction(DateTimeOffset timestamp);

        /// <summary>
        /// Retrieves all successfully committed transactions that have ever occurred in the system.
        /// </summary>
        /// <returns>Committed transactions</returns>
        public abstract IList<ITransaction> GetTransactions();
        /// <summary>
        /// Retrieves all successfully committed transactions that have ever occurred on <paramref name="account"/>.
        /// </summary>
        /// <param name="account">The account</param>
        /// <returns>Committed transactions</returns>
        public abstract IList<ITransaction> GetTransactions(IAccount account);
        /// <summary>
        /// Retrieves all successfully committed transactions that have occurred on <paramref name="account"/>
        /// after <paramref name="after"/>
        /// </summary>
        /// <param name="account">The account</param>
        /// <param name="after">Beginning time for transactions</param>
        /// <returns>Committed transactions</returns>
        public abstract IList<ITransaction> GetTransactions(IAccount account, DateTimeOffset? after);
        /// <summary>
        /// Retrieves all successfully committed transactions that have occurred on <paramref name="account"/>
        /// after <paramref name="after"/> and before <paramref name="before"/>
        /// </summary>
        /// <param name="account">The account</param>
        /// <param name="after">Beginning time for transactions</param>
        /// <param name="before">End time for transactions</param>
        /// <returns>Committed transactions</returns>
        public abstract IList<ITransaction> GetTransactions(IAccount account, DateTimeOffset? after, DateTimeOffset? before);

        /// <summary>
        /// Creates a new contact
        /// </summary>
        /// <returns>The new contact</returns>
        public abstract IContact CreateContact();

        /// <summary>
        /// Retrieves the contact with the ID property matching the supplied id parameter
        /// </summary>
        /// <param name="id">The ID property of the contact</param>
        /// <returns>The contact or null if none is found</returns>
        public abstract IContact GetContact(Guid id);

        public abstract void Install();

        #region IDisposable Members

        /// <summary>
        /// Release any resources associated with this provider
        /// </summary>
        public abstract void Dispose();

        #endregion
    }
}
